# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html


# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
import json
import os

import scrapy
from scrapy.pipelines.images import ImagesPipeline
# 导入如下类，可以对配置文件setting中的内容进行获取
from scrapy.utils.project import get_project_settings


class TurorialPipeline:
    def process_item(self, item, spider):
        return item


class ItcastSpiderPipeline(object):
    """
    处理在爬虫中返回的item数据的类,将传递过来的数据进行永久化
    """

    def __init__(self):
        """
        初始化类中所需的数据，可选操作
        """
        # 创建了一个文件，将文件的保存类型设置为utf-8
        self.file = open('teachers.json', 'w', encoding='utf-8')

    def process_item(self, item, spider):
        """
        对item数据进行处理的方法，该方法必须要写，参数固定
        :param item:
        :param spider:
        :return:
        """
        # 将数据由列表格式先变换为字典格式，再变换为json格式的数据
        json_text = json.dumps(dict(item), ensure_ascii=False)+"\n"

        # 保存数据为utf-8的格式
        self.file.write(json_text)

    def close_spider(self, spider):
        """
        爬虫关闭时执行的函数，可选操作，可以用来对资源进行回收
        :return:
        """
        self.file.close()


class DouyuPipeline(ImagesPipeline):
    """
    自定义imagepipeline处理管道，继承了ImagesPipeline
    以下的方法为模版方法，用来对图片进行下载
    """

    # 获取setting文件中设置的图片路径
    IMAGES_STORE = get_project_settings().get('IMAGES_STORE')

    # 开始对图片的url进行处理
    def get_media_requests(self, item, info):
        image_url = item['vertical_src']
        # 去请求图片的url，并交给下面的方法来进行处理
        yield scrapy.Request(image_url)

    # 对已经下载好的图片信息进行处理
    def item_completed(self, results, item, info):
        # 提取图片的url信息，标准格式
        image_path = [x["path"] for ok, x in results if ok]

        # 将图片重新命名
        os.rename(self.IMAGES_STORE + '/' + image_path[0], self.IMAGES_STORE+'/'+item['room_id']+'-'+item['room_name']+'.jpg')

        # 更新图片路径
        item['vertical_src'] = self.IMAGES_STORE+'/'+item['room_id']+'-'+item['room_name']

        # 最后一定得将item返回
        return item


class TencentspiderPipeline(object):
    """
    处理爬虫所爬取到的数据
    """
    def __init__(self):
        """
        初始化操作，在爬虫运行过程中只执行一次
        """
        self.file = open('tencent_position.json', 'w', encoding='utf-8')

    def process_item(self, item, spider):
        # 现将item数据转为字典类型，再将其保存为json文件
        text = json.dumps(dict(item), ensure_ascii=False)+'\n'
        print(text)
        # 写入本地
        self.file.write(text)
        # 会将item打印到屏幕上，方便观察
        return item

    def close_spider(self, spider):
        """
        爬虫关闭时所执行的操作，在爬虫运行过程中只执行一次
        """
        self.file.close()


class SunSpiderPipeline(object):
    def __init__(self):
        self.file = open('sun.json', 'w', encoding='utf-8')

    def process_item(self, item, spider):
        text = json.dumps(dict(item), ensure_ascii=False) + '\n'
        # 写入本地
        self.file.write(text)
        return item

    def close_spider(self, spider):
        self.file.close()


class IpSpiderPipeline(object):
    """
    处理爬虫所爬取到的数据
    """
    def __init__(self):
        """
        初始化操作，在爬虫运行过程中只执行一次
        """
        self.file = open('ips.json', 'w', encoding='utf-8')

    def process_item(self, item, spider):
        # 现将item数据转为字典类型，再将其保存为json文件
        text = json.dumps(dict(item), ensure_ascii=False)+'\n'
        # 写入本地
        self.file.write(text)
        # 会将item打印到屏幕上，方便观察
        return item

    def close_spider(self, spider):
        """
        爬虫关闭时所执行的操作，在爬虫运行过程中只执行一次
        """
        self.file.close()


import urllib
import pymongo

from pymongo import MongoClient
# 从设置文件中导入所需的mongodb配置文件
from turorial.settings import MONGODB_HOST
from turorial.settings import MONGODB_PORT
from turorial.settings import MONGODB_DB_NAME
from turorial.settings import MONGODB_COLL_NAME


class DoubanspiderPipeline(object):
    def __init__(self):
        """
        初始化数据库的连接
        """
        # 创建数据库连接
        # 出现问题：pymongo.errors.InvalidURI: Username and password must be escaped according to RFC 3986, use urllib.parse.quote_plus()
        # user_name = urllib.parse.quote_plus('user_name')
        # password = urllib.parse.quote_plus('password')
        # url = 'mongodb://%s:%s@%s:%s/?authSource=admin&authMechanism=MONGODB-CR' % (user_name, password, MONGODB_HOST, MONGODB_PORT)
        self.client = MongoClient('mongodb://localhost:27017')
        # 指定数据库
        db = self.client[MONGODB_DB_NAME]
        # 指定集合
        self.collection = db[MONGODB_COLL_NAME]

    def process_item(self, item, spider):
        """
        将数据保存到数据库之中
        """
        # item数据为类字典类型，首先得将其转换为字典类型
        data = dict(item)
        self.collection.insert(data)
        return item

    def close_spider(self, spider):
        """
        爬虫运行结束之后关闭数据库
        """
        self.client.close()